package cn.tonyandmoney.voicenotes.alarm

import android.content.Intent
import android.text.TextUtils
import android.view.Gravity
import android.widget.LinearLayout
import android.widget.TextView
import cn.tonyandmoney.anko.extend.rightDrawableResId
import cn.tonyandmoney.baidu.ISpeech
import cn.tonyandmoney.voicenotes.R
import cn.tonyandmoney.voicenotes.alarm.entity.TAlarm
import cn.tonyandmoney.voicenotes.alarm.model.FileWriterEmitter
import cn.tonyandmoney.voicenotes.alarm.utils.AlarmUtils
import cn.tonyandmoney.voicenotes.greendao.utils.GreenDaoHelper
import cn.tonyandmoney.voicenotes.notes.config.Constants
import cn.tonyandmoney.voicenotes.ui.MainActivity
import cn.tonyandmoney.voicenotes.utils.DateUtils
import com.afollestad.materialdialogs.MaterialDialog
import com.bigkoo.pickerview.builder.TimePickerBuilder
import com.bigkoo.pickerview.listener.OnTimeSelectListener
import com.loonggg.lib.alarmmanager.clock.AlarmManagerUtil
import com.loonggg.lib.alarmmanager.clock.view.SelectRemindCyclePopup
import com.zlzsy.app.base.ui.BaseActivity
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.jetbrains.anko.*
import org.jetbrains.anko.sdk25.coroutines.textChangedListener
import java.util.*

class CreateAlarmActivity : BaseActivity(), AnkoLogger {

    private lateinit var mLayout: LinearLayout
    private var mAlarm = TAlarm()
    private val alarmDao = GreenDaoHelper.session().tAlarmDao
    private val speaker = ISpeech.INSTANCE!!.getSpeaker()
    private val spId = UUID.randomUUID().toString()

    override fun initView() {
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        val id = intent.getLongExtra("id", -1)
        if (id > 0) {
            mAlarm = alarmDao.load(id)
        }
        verticalLayout {
            mLayout = this
            gravity = Gravity.CENTER_HORIZONTAL
            padding = dip(25)
            textView {
                hint = "选择时间"
                text = mAlarm.date
                setOnClickListener { selectTime(this) }
            }.lparams(wrapContent, wrapContent) {
                bottomMargin = dip(30)
            }
            textView { setBackgroundResource(R.color.line_and_outline_grey) }.lparams(matchParent, dip(1))
            editText {
                hint = "请输入提示"
                lines = 1
                singleLine = true
                backgroundResource = android.R.color.transparent
                textChangedListener {
                    onTextChanged { sequence, _, _, _ ->
                        mAlarm.name = sequence?.toString()
                    }
                }
                if (id > 0) setText(mAlarm.name)
            }.lparams(matchParent, dip(45))
            textView { setBackgroundResource(R.color.line_and_outline_grey) }.lparams(matchParent, dip(1))
            textView {
                topPadding = dip(15)
                bottomPadding = dip(15)
                hint = "请选择重复方式（默认只提醒一次）"
                rightDrawableResId = R.drawable.ic_chevron_right_black_24dp
                setOnClickListener { selectRemindCycle(this) }
                if (id > 0) setRemindByFlag(this)
            }.lparams(matchParent, wrapContent)
            textView { setBackgroundResource(R.color.line_and_outline_grey) }.lparams(matchParent, dip(1))
            linearLayout {
                orientation = LinearLayout.HORIZONTAL
                topPadding = dip(15)
                bottomPadding = dip(15)
                textView {
                    text = "铃声"
                }.lparams(wrapContent, wrapContent)
                textView {
                    hint = "请选择铃声"
                    rightDrawableResId = R.drawable.ic_chevron_right_black_24dp
                    gravity = Gravity.END
                    compoundDrawablePadding = dip(10)
                    setOnClickListener { selectRingWay(this) }
                    if (id > 0) setRingWay(this)
                }.lparams(matchParent, wrapContent)
            }.lparams(matchParent, wrapContent)
            textView { setBackgroundResource(R.color.line_and_outline_grey) }.lparams(matchParent, dip(1))
            textView {

            }.lparams(matchParent, 0, 1f)
            textView {
                gravity = Gravity.CENTER
                text = "确定"
                textColor = resources.getColor(android.R.color.white)
                backgroundResource = R.color.colorPrimary
                setOnClickListener { addAlarm() }
            }.lparams(matchParent, dip(45))

        }
    }

    @Synchronized
    private fun getAudioForText() {
        if (TextUtils.isEmpty(mAlarm.name)) {
            longToast("请输入语音提示内容")
            return
        }
        hideLoadingDialog()
        val dialog = MaterialDialog.Builder(this)
                .title("正在获取语音数据...")
                .progress(false, 100)
                .show()

        val pListener: ((Int) -> Unit) = {
            dialog.setProgress(it)
        }

        val outPath = Constants.sDataRootPath + "/synthesize/" + DateUtils.toYYYYMMDDHHmmss() + ".pcm"

        Observable.create<String> {
            speaker.synthesize(spId, mAlarm.name, FileWriterEmitter(it, outPath, pListener))
        }.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    info("get success->$it")
                    dialog.dismiss()
                    addAlarm(it)
                }, {
                    dialog.dismiss()
                    error("get alarm ring",it)
                    hideLoadingDialog()
                    showAlert("语音闹铃获取错误，请重试。")
                })
    }

    /**
     * 保存闹钟，语音提示闹钟
     * @param path  语音文本保存路径
     */
    private fun addAlarm(path: String) {
        showLoadingDialog("正在保存...")
        mAlarm.ring = 2
        mAlarm.voice = path
        if (mAlarm.id==null||mAlarm.id<=0){
            mAlarm.id = alarmDao.insert(mAlarm)
        }else{
            alarmDao.update(mAlarm)
        }
        val aIntent = Intent(getString(R.string.broadcast_intent))
        aIntent.putExtra("voice", path)
        info("voice: $path")
        setAlarm(aIntent)
        hideLoadingDialog()
        longToast("保存成功...")
        finish()
    }

    private fun addAlarm() {
        if (TextUtils.isEmpty(mAlarm.date)) {
            longToast("请选择时间")
            return
        }

        val times = AlarmUtils.getTimesFromString(mAlarm.date)
        if (times.size < 2) {
            longToast("时间错误，请重新选择。")
            return
        }

        if (mAlarm.ring == 2) {
            getAudioForText()
            return
        }

        if (TextUtils.isEmpty(mAlarm.name)) {
            mAlarm.name = "您有一个新的闹钟"
        }

        if (mAlarm.id!=null&&mAlarm.id > 0) {
            alarmDao.update(mAlarm)
        } else {
            mAlarm.id = alarmDao.insert(mAlarm)
        }
        val intent = Intent(getString(R.string.broadcast_intent))
        setAlarm(intent)
        longToast("闹钟设置成功")
        finish()
    }

    private fun setAlarm(aIntent: Intent) {
        val id = mAlarm.id.toInt()
        AlarmManagerUtil.cancelAlarm(this, aIntent.action, id)
        val times = AlarmUtils.getTimesFromString(mAlarm.date)
        if (times.size < 2) {
            longToast("时间错误，请重新选择。")
            return
        }
        val hour = times[0]
        val minute = times[1]
        val ring = mAlarm.ring

        val cycle = mAlarm.cycle
        when (cycle) {
            0 -> {
                AlarmManagerUtil.setAlarm(this, 0, hour, minute, id, 0, mAlarm.name, ring, aIntent)
            }
            -1 -> {
                AlarmManagerUtil.setAlarm(this, 1, hour, minute, id, 0, mAlarm.name, ring, aIntent)
            }
            else -> {
                val weeksStr = AlarmUtils.parseRepeat(cycle, 1)
                val weeks = weeksStr.split(",".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()
                for (i in weeks.indices) {
                    AlarmManagerUtil.setAlarm(this, 2, hour, minute, id, Integer.parseInt(weeks[i]), mAlarm.name, ring, aIntent)
                }
            }
        }
    }

    private fun selectTime(textView: TextView) {
        val calendar = Calendar.getInstance()

        if (!TextUtils.isEmpty(mAlarm.date)) {
            calendar.time = AlarmUtils.parseDate(mAlarm.date)
        }

        TimePickerBuilder(this, OnTimeSelectListener { date, v ->
            mAlarm.date = AlarmUtils.dateFormat(date)
            textView.text = mAlarm.date
        })
                .setType(booleanArrayOf(false, false, false, true, true, false))
                .setCancelText("取消")
                .setSubmitText("确定")
                .setOutSideCancelable(false)
                .setDate(calendar)
                .isCyclic(false)
                .build()
                .show()
    }

    /**
     * 选择提醒方式
     */
    private fun selectRingWay(textView: TextView) {
        MaterialDialog.Builder(this)
                .items("震动", "铃声", "语音")
                .itemsCallbackSingleChoice(mAlarm.ring, MaterialDialog.ListCallbackSingleChoice { dialog, _, which, text ->
                    textView.text = text
                    mAlarm.ring = which
                    dialog.dismiss()
                    return@ListCallbackSingleChoice true
                })
                .positiveText("确定")
                .negativeText("取消")
                .autoDismiss(true)
                .cancelable(false)
                .show()
    }

    private fun setRingWay(textView: TextView) {
        when (mAlarm.ring) {
            0 -> textView.text = "震动"
            1 -> textView.text = "铃声"
            2 -> textView.text = "语音"
        }
    }

    private fun selectRemindCycle(textView: TextView) {
        val fp = SelectRemindCyclePopup(this)
        fp.showPopup(mLayout)
        fp.setOnSelectRemindCyclePopupListener { flag, ret ->
            when (flag) {
                0, 1, 2, 3, 4, 5, 6 -> {   // 星期一到周日
                }
                7 -> {    // 确定
                    val repeat = Integer.valueOf(ret)
                    textView.text = AlarmUtils.parseRepeat(repeat, 0)
                    mAlarm.cycle = repeat
                    fp.dismiss()
                }
                8 -> {
                    textView.text = "每天"
                    mAlarm.cycle = 0
                    fp.dismiss()
                }
                9 -> {
                    textView.text = "只响一次"
                    mAlarm.cycle = -1
                    fp.dismiss()
                }
                else -> {
                }
            }
        }
    }

    private fun setRemindByFlag(textView: TextView) {
        when (mAlarm.cycle) {
            0 -> textView.text = "每天"
            -1 -> textView.text = "只响一次"
            else -> {
                textView.text = AlarmUtils.parseRepeat(mAlarm.cycle, 0)
            }
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        speaker.removeSynthsizeListener(spId)
    }

}